from djcontrol import *

from Tkinter import *
import djcontrolutil


class DjMenu(DjControl):
	"""
	Menu widget, based on Tkinter Menu.
	
	Properties:
	*bgcolor* - Background color of the listbox. RGB triplet, such as (255,0,0) for pure red. Evidently does not have effect on Windows.
	*color* - Foreground color of the listbox. RGB triplet. Evidently does not have effect on Windows.
	*borderwidth* - An integer, width of border in pixels. Evidently does not have effect on Windows.
	*borderstyle* - Border style. One of 'sunken','raised','groove','ridge','flat'. Default is 'sunken'. Evidently does not have effect on Windows.
	*selectioncolor* - Color of text when an item is selected. RGB triplet. Evidently does not have effect on Windows.
	*font* - Set font of items in the listbox. Standard tkinter font format, such as ('Times New Roman', 12, 'normal'). Evidently does not have effect on Windows.
	"""
	
	# Note that only names beginning with '_', or the special case basecontrol, should be used.
	_autoProperties = None
	_topmenu = None
	_tagdictionary = None
	basecontrol = 0
	
	def __init__(self, parent, *args):
		"""Constructs a menu."""
		
		# Keep a reference to the "top" most menu of the menubar.
		if isinstance(parent, DjMenu):
			self.basecontrol = Menu(parent.basecontrol, tearoff=0)
			self._topmenu = parent._topmenu
		else:
			parent = djcontrolutil.getbasecontrol(parent)
			self.basecontrol = Menu(parent, tearoff=0)
			self._topmenu = self
			
		# Tags
		self._tagdictionary = {}
		self._keyshortcuts = {}
		
		# For each of the arguments. If a list, submenu. If a _, separator. If a string, item.
		# Submenus are also created using this same code. These resulting DjMenu object, though, is not necessary.
		i=0
		index = 0
		while i<len(args):
			menuitem = args[i]
			if isinstance(menuitem, list):
				# We will treat this like a submenu.
				submenu = menuitem
				submenu_name = submenu[0]
				
				
				submenu_data = submenu[1:]
				newmenu = DjMenu(self, *submenu_data)
				newmenu.basecontrol.config(tearoff=0) # Default property
				
				#get alt key
				submenu_name, submenu_nameAlt = djcontrolutil.stringToUnderlinePosition(submenu_name)
				if submenu_nameAlt!=-1:
					self.basecontrol.add_cascade(label=submenu_name, menu=newmenu.basecontrol, underline=submenu_nameAlt)
				else:
					self.basecontrol.add_cascade(label=submenu_name, menu=newmenu.basecontrol)
					
				index += 1
				
			# But, when adding a previously made menu, what shold the label be?
			elif isinstance(menuitem, Menu) or isinstance(menuitem, DjMenu):
				# Add a menu as a submenu
				submenu = djcontrolutil.getbasecontrol(menuitem)
				self.basecontrol.add_cascade(label='', menu=submenu)
				index+=1
			elif menuitem=='_':
				self.basecontrol.add_separator()
				index += 1
			elif isinstance(menuitem,str):
				# Treat this as a menu item.
				kwargs = {}
				parts = menuitem.split('|')
				
				# First item: Label text
				label = parts[0]
				label, pos = djcontrolutil.stringToUnderlinePosition(label)
				if pos!=-1: kwargs['underline'] = pos
				kwargs['label'] = label
				
				# Second item: Accelerator text
				if len(parts)>1 and parts[1]: kwargs['accelerator']=parts[1]
				
				# Fourth item: type
				strType='command' #By default
				var = None
				if len(parts)>3:
					type=parts[3]
					if type not in ('radio','checkbox'): raise ValueError, 'Unknown menu item type'
					if type=='radio': strType ='radiobutton'
					elif type=='checkbox': 
						strType ='checkbutton'
						var = IntVar()
						var.set(1)
						kwargs['variable']=var
				
				# Third item: Tag text, that can be queried and accessed later. Now depends in index, which isn't ideal.
				if len(parts)>2: 
					tagname=parts[2]
					if tagname: self._topmenu._tagdictionary[tagname] = (self.basecontrol, index, var)
				
				# Treat the next argument passed in as a command
				i+=1
				if args[i]!=None: kwargs['command'] = args[i]
				
				# Create the menuitem
				self.basecontrol.add(strType, **kwargs)
				
				# Keep track of the shortcut
				if 'accelerator' in kwargs:
					self._topmenu._keyshortcuts[kwargs['accelerator']] = args[i]
				
				index += 1
			else:
				raise ValueError, 'Unknown menu entry.'
			i+=1
		
		self._autoProperties = {
		'bgcolor': ('background',djcontrolutil.colorToString,djcontrolutil.stringToColor),
		'color': ('foreground',djcontrolutil.colorToString,djcontrolutil.stringToColor),
		'selectioncolor': ('selectcolor',djcontrolutil.colorToString,djcontrolutil.stringToColor),
		'borderwidth': ('borderwidth',None,None),
		'borderstyle': ('relief', djcontrolutil.stringToRelief,djcontrolutil.reliefToString),
		'font': ('font',None,None),
		}
		
		
	def set_menuitem_property(self,strTag, strAttribute, value):
		"""Set a property of a menuItem"""
		if strTag not in self._tagdictionary: raise ValueError, 'Could not find menuitem Tag.'
		menu, index = self._tagdictionary[strTag][0],self._tagdictionary[strTag][1]
		menu.entryconfig(index, **{strAttribute:value})
		
	def get_menuitem_property(self,strTag, strAttribute):
		"""Get a property of a menuItem"""
		if strTag not in self._tagdictionary: raise ValueError, 'Could not find menuitem Tag.'
		menu, index = self._tagdictionary[strTag][0], self._tagdictionary[strTag][1]
		return menu.entrycget(index, strAttribute)
		
	def get_menuitem_checked(self, strTag):
		"""Determine if a menuitem is checked. The menuItem must have been set up as a checkbox, for example 'To&ggle||TOGGLE|checkbox' sets up a checkbox menu item with tag 'TOGGLE'."""
		if strTag not in self._tagdictionary: raise ValueError, 'Could not find menuitem Tag.'
		var = self._tagdictionary[strTag][2]
		if not var: raise ValueError, 'Menuitem is not a checkbox.'
		return var.get()
	
	def set_menuitem_checked(self, strTag, value):
		"""Set if a menuitem is checked. The menuItem must have been set up as a checkbox, for example 'To&ggle||TOGGLE|checkbox' sets up a checkbox menu item with tag 'TOGGLE'."""
		if strTag not in self._tagdictionary: raise ValueError, 'Could not find menuitem Tag.'
		var = self._tagdictionary[strTag][2]
		if not var: raise ValueError, 'Menuitem is not a checkbox.'
		var.set(value)
	
	def disable_menuitem(self, strTag):
		"""Disable menuitem so that it cannot be chosen."""
		self.set_menuitem_property(strTag, 'state', DISABLED)
		
	def enable_menuitem(self, strTag):
		"""Enable menuitem (if it has been disabled) so that it can be chosen."""
		self.set_menuitem_property(strTag, 'state', NORMAL)	
		
	def set_contextual(self, parent):
		"""Turn this into a contextual menu that will appear upon right-click."""
		#See http://effbot.org/tkinterbook/menu.htm
		def popup(event):
			self.basecontrol.post(event.x_root, event.y_root)
		parent = djcontrolutil.getbasecontrol(parent)
		parent.bind("<Button-3>", popup)
	
	_customProperties = tuple()
	